package com.example.hello.service.impl;

import com.example.hello.mapper.BookMapper;
import com.example.hello.mapper.UserBookMapper;
import com.example.hello.mapper.UserBorrowCertificateMapper;
import com.example.hello.mapper.UserMapper;
import com.example.hello.pojo.*;
import com.example.hello.service.BorrowService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

@Service
public class BorrowServiceImpl implements BorrowService {

    @Autowired
    private BookMapper bookMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserBookMapper userBookMapper;

    @Autowired
    private UserBorrowCertificateMapper certificateMapper;

    @Override
    @Transactional
    public UserBook borrowBook(Long userId, Integer bookId) {
        User user = userMapper.getById(userId);

        UserBorrowCertificate userBorrowCertificate = certificateMapper.getById(user.getCertificateId());

        if (userBorrowCertificate == null) {
            throw new RuntimeException("未找到借阅证，请联系管理员开通借阅权限");
        }
        if (user.getCredit() < 60) {
            throw new RuntimeException("信誉度过低，无法借阅，请联系管理员");
        }

        // 1. 查询图书信息
        Book book = bookMapper.getBookById(bookId);
        if (book == null) {
            throw new RuntimeException("图书未入库\n请联系管理员添加");
        }
        // 2. 检查图书库存是否充足
        if (book.getLastNum() <= 0) {
            throw new RuntimeException("库存不足，无法借阅");
        }
        // 3. 查询用户当前活跃（未归还）借阅记录数量
        int activeCount = userBookMapper.countActiveBorrows(userId);
        if (activeCount >= userBorrowCertificate.getMaxBorrowBookNum()) {
            throw new RuntimeException("您最多只能借阅"+userBorrowCertificate.getMaxBorrowBookNum()+"本图书");
        }
        // 4. 检查该用户是否已借阅过此图书且未归还
        UserBook activeBorrow = userBookMapper.getActiveBorrowForBook(userId, bookId);
        if (activeBorrow != null) {
            throw new RuntimeException("您已借阅过此图书，无法重复借阅");
        }
        // 5. 更新图书库存，将剩余数量减 1
        int newLastNum = book.getLastNum() - 1;
        int updateCount = bookMapper.updateBookLastNum(bookId, newLastNum);
        if (updateCount <= 0) {
            throw new RuntimeException("更新库存失败");
        }
        // 6. 插入借书记录
        UserBook userBook = new UserBook();
        userBook.setUserId(userId);
        userBook.setBookId(bookId);
        Date now = new Date();
        userBook.setBorrowDate(now);
        userBook.setCreatedAt(now);
        userBook.setUpdatedAt(now);
        userBook.setMaxBorrowBookDay(userBorrowCertificate.getMaxBorrowDay());
        int insertCount = userBookMapper.insertUserBook(userBook);
        if (insertCount <= 0) {
            throw new RuntimeException("插入借书记录失败");
        }
        // 7. 将图书借阅次数加1
        bookMapper.incrementBorrowNum(bookId);
        return userBook;
    }

    @Override
    public List<Book> getBorrowedBooksByUserId(Long userId) {
        return userBookMapper.getBorrowedBooksByUserId(userId);
    }

    @Override
    @Transactional
    public Res returnBook(Long userId, Integer bookId) {
        // 1. 更新 user_book 表中未归还的记录，设置归还时间为当前时间
        int count = userBookMapper.updateReturnDate(userId, bookId, new Date());
        if (count == 0) {
            return Res.error("还书失败：未找到借阅记录或图书已归还");
        }
        // 2. 更新 book 表，剩余数量加 1
        int updateCount = bookMapper.incrementLastNum(bookId);
        if (updateCount == 0) {
            throw new RuntimeException("还书失败：更新图书库存失败");
        }
        return Res.success("还书成功");
    }

    @Override
    public Integer findBookIdByIsbn(Long userId, String bookIsbn) {
        Integer bookId = bookMapper.findBookIdByIsbn(bookIsbn);
        borrowBook(userId, bookId);
        return bookId;
    }

    @Override
    public List<Book> getAllBorrowedBooksByUserId(Long userId) {
        return userBookMapper.getAllBorrowedBooksByUserId(userId);
    }

    @Override
    public List<Book> getAllReturnedBooksByUserId(Long userId) {
        return userBookMapper.getAllReturnedBooksByUserId(userId);
    }

}